package com.xiangxiao.rpan.storage.download.url;

import com.xiangxiao.rpan.storage.core.DownloadFileTool;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItem;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;

/**
 * @auther xiangxiao
 * @email 573768011@qq.com
 * @data 2023/12/1 17:40
 */
@Slf4j
@Component(value = "downloadURLAndMutipartFile")
public class DownloadURLAndMutipartFile implements DownloadFileTool {
  @Override
  public void readStreamToFile(String path, HttpServletResponse response) throws IOException {
    // Create a resource from the URL
    URL urlObj = new URL(path);
    File file = new File(path);
    String filename = file.getName();
    HttpURLConnection connection = (HttpURLConnection) urlObj.openConnection();
    connection.setRequestMethod("GET");
    connection.setConnectTimeout(10000);
    connection.setReadTimeout(60000);
    connection.setDoOutput(true);
    DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
    DiskFileItem fileItem = (DiskFileItem) fileItemFactory.createItem("file",
        MediaType.ALL_VALUE, true, filename);
    fileItem.getOutputStream().flush();
    try (ReadableByteChannel readableByteChannel = Channels.newChannel(connection.getInputStream());
         OutputStream outputStream = fileItem.getOutputStream();
         WritableByteChannel writableByteChannel = Channels.newChannel(outputStream)) {
      // Create a byte buffer to store the file content
      ByteBuffer buffer = ByteBuffer.allocateDirect(1024 << 2);

      // Read the file content into the byte buffer
      while (readableByteChannel.read(buffer) != -1) {
        // Prepare the byte buffer to be read again
        buffer.flip();
        while (buffer.hasRemaining()) {
          writableByteChannel.write(buffer);
        }
        buffer.clear();
      }
    } catch (Exception e) {
      e.printStackTrace();
      // Handle network or file IO exceptions here
      log.error("Error uploading file", e);
    }
  }

  @Override
  public String convertMuitlFileToStream(MultipartFile multipartFile, Integer chunkNumber, Integer totalChunks, long blockSize) {
    // todo
    return null;
  }
}
